package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"time"
	"strconv"
	"path"
	"strings"
	"bytes"
)

func main() {
	start := time.Now().Unix();
	// fileSize, fileLineNum := getFileInfo("D:\\all.csv")
	// fmt.Println(strconv.Itoa(fileSize) + ":" + strconv.Itoa(fileLineNum))

	splitFile("D:\\ttt.csv", 5000)

	fmt.Printf("time:%d", (time.Now().Unix() - start))
}

func splitFile(filePath string, newFileLineNum int) {
	fi, err := os.Open(filePath)
	if err != nil {
		fmt.Printf("Error: %s\n", err)
		return
	}
	defer fi.Close()

	fileSuffix := path.Ext(path.Base(filePath))
	filenameOnly := strings.TrimSuffix(path.Base(filePath), fileSuffix)

	br := bufio.NewReader(fi)
	num := 0
	fileNum := 0
	sizeTotal := 0
	var bufferBytes []byte
	for {
		a, _, c := br.ReadLine()
		num++
		bufferBytes = BytesCombine(bufferBytes, a, []byte("\n"))

		if c == io.EOF {
			fileNum++
			tempFileName := filenameOnly + "_" + strconv.Itoa(fileNum) + fileSuffix
			fmt.Println("new file :" + tempFileName)
			f, err := os.OpenFile(tempFileName, os.O_CREATE|os.O_WRONLY, os.ModePerm)
			if err != nil {
				fmt.Println(err)
				return
			}
			f.Write(bufferBytes[0:len(bufferBytes)-1])
			f.Close()

			bufferBytes = []byte("")

			break
		}

		if num == newFileLineNum {
			num = 0
			fileNum++
			tempFileName := filenameOnly + "_" + strconv.Itoa(fileNum) + fileSuffix
			fmt.Println("new file :" + tempFileName)
			f, err := os.OpenFile(tempFileName, os.O_CREATE|os.O_WRONLY, os.ModePerm)
			if err != nil {
				fmt.Println(err)
				return
			}
			f.Write(bufferBytes[0:len(bufferBytes)-1])
			f.Close()

			bufferBytes = []byte("")
		}
		// fmt.Println(a)
		sizeTotal += len(a)
	}

}

//BytesCombine 多个[]byte数组合并成一个[]byte
func BytesCombine(pBytes ...[]byte) []byte {
	sep := []byte("")
	return bytes.Join(pBytes, sep)
}

func getFileInfo(filePath string) (fileSize int, fileLineNum int) {
	fi, err := os.Open(filePath)
	if err != nil {
		fmt.Printf("Error: %s\n", err)
		return
	}
	defer fi.Close()

	br := bufio.NewReader(fi)
	num := 0
	sizeTotal := 0
	for {
		a, _, c := br.ReadLine()
		if c == io.EOF {
			break
		}
		num++
		// fmt.Println(a)
		sizeTotal += len(a)
	}

	return sizeTotal, num
}
